home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 8
- MORE INHERITANCE
-
- In the last chapter we developed a model using modes of
- transportation to illustrate the concept of inheritance. In this
- chapter we will use that model to illustrate some of the finer
- points of inheritance and what it can be used for. If it has been
- a while since you read and studied chapter 7, it would be good for
- you to return to that material and review it in preparation for a
- more detailed study of the topic of inheritance.
-
-
-
- REORGANIZED FILE STRUCTURE
- _________________________________________________________________
-
- A close examination of the file named ================
- INHERIT1.CPP will reveal that it is identical to INHERIT1.CPP
- the program developed in chapter 7 named ================
- ALLVEHIC.CPP except that the program text is
- rearranged. The biggest difference is that some
- of the simpler methods in the classes have been changed to inline
- code to shorten the file considerably. In a practical programming
- situation, methods that are this short should be programmed inline
- since the actual code to return a simple value is shorter than the
- code required to actually send a message to a non-inline method.
-
- The only other change is the reordering of the classes and
- associated methods with the classes all defined first, followed by
- the main program. This puts all class interface definitions on a
- single page to make the code easier to study. The implementations
- for the methods are deferred until the end of the file where they
- are available for quick reference but are not cluttering up the
- class definitions which we wish to study carefully in this chapter.
- This should be an indication to you that there is considerable
- flexibility in the way the classes and methods can be arranged in
- C++. Of course you realize that this violates the spirit of C++
- and its use of separate compilation, but is only done here for
- convenience.
-
- As mentioned before, the two subclasses, car and truck, each have
- a variable named passenger_load which is perfectly legal, and the
- car class has a method of the same name, initialize(), as one
- defined in the super-class named vehicle. The rearrangement of the
- files in no way voids this allowable repeating of names.
-
- After you have convinced yourself that this program is truly
- identical to the program named ALLVEHIC.CPP from chapter 7, compile
- and execute it with your compiler to assure yourself that this
- arrangement is legal.
-
-
-
-
- page 8-1
-
- Chapter 8 - More Inheritance
-
- THE SCOPE OPERATOR
- _________________________________________________________________
-
- Because the method initialize() is defined in the car subclass, it
- hides the method of the same name which is part of the parent
- class, and there may be times you wish to send a message to the
- method in the parent class for use in the subclass object. This
- can be done by using the scope operator in the following manner in
- the main program;
-
- sedan.vehicle::initialize(4,3500.0);
-
- As you might guess, the number and types of parameters must agree
- with those of the method in the parent class because it will
- respond to the message.
-
-
- HIDDEN METHODS
- _________________________________________________________________
-
- Examine the file named INHERIT2.CPP carefully ================
- and you will notice that it is a repeat of the INHERIT2.CPP
- last example program with a few minor changes. ================
-
- You will notice that the derived classes named
- car and truck do not have the keyword public prior to the name of
- the parent class in the first line of each. The keyword public,
- when included prior to the parent's name, makes all of the methods
- defined in the parent class available for use in the derived class
- just as if they were defined as part of the subclass. Therefore,
- in the previous program, we were permitted to call the methods
- defined as part of the parent class from the main program even
- though we were working with an object of one of the derived
- classes. One example of when we did this was when we sent a
- message to the sedan to get its weight in an output statement of
- the main program.
- In the present program, without the keyword public prior to the
- parent class name, the only methods available for objects of the
- car class, are those that are defined as part of the class itself,
- and therefore we only have the methods named initialize() and
- passengers() available for use with objects of class car. In this
- program, the only inheritance is that of variables since the two
- variables are inherited into objects of class car but even they are
- not directly available as will soon be seen.
-
- When we declare an object of type car, according to the definition
- of the C++ language, it contains three variables. It contains the
- one defined as part of its class named passenger_load and the two
- that are part of its parent class, wheels and weight. The only
- variable that is available for direct use within its methods is the
- one defined as part of its own class, the other two are effectively
- hidden from its methods. You will note that there is no way in
- this program that we can ever use the variables named wheels or
- weight directly in either an external program or one of the methods
-
- page 8-2
-
- Chapter 8 - More Inheritance
-
- of this class. The variables are a part of an object of class car
- when each is declared and is stored as part of the object, but the
- only way to use them is through use of the methods defined as part
- of the parent class. They are initialized in line 86 to illustrate
- the means used to access them.
-
- We will show you a way to access the parent class variables
- directly within local methods shortly in this chapter. For now,
- we will return to the use of the subclasses in this example
- program.
-
- The observant student will notice that several of the output
- statements have been commented out of the main program since they
- are no longer legal or meaningful operations. Lines 56 through 58
- have been commented out because the methods named get_weight() and
- wheel_loading() are not inherited into the car class without the
- keyword public in the car class definition. You will notice that
- initialize() is still available but this is the one in the car
- class, not the method of the same name in the vehicle class.
-
- Moving on to the use of the truck class in the main program, we
- find that lines 62 and 64 are commented out for the same reason as
- given above, but lines 65 and 66 are commented out for an entirely
- different reason. Even though the method named efficiency() is
- available and can be called as a part of the truck class, it cannot
- be used because we have no way to initialize the wheels or weight
- of the truck objects. We can get the weight of the truck objects,
- as we have done in line 104, by using the scope resolution
- operator, but since the weight has no way to be initialized, the
- result is meaningless and lines 65 and 66 are commented out.
-
- As you have surely guessed by now, there is a way around all of
- these problems and we will cover them shortly. In the meantime,
- be sure to compile and execute this example program to see that
- your compiler gives the same result. It would be a good exercise
- for you to reintroduce some of the commented out lines to see what
- sort of an error message your compiler issues for these errors.
-
-
- INITIALIZING ALL DATA
- _________________________________________________________________
-
- If you will examine the example program named ================
- INHERIT3.CPP, you will find that we have fixed INHERIT3.CPP
- the initialization problem that we left dangling ================
- in the last example program.
-
- The method named init_truck() now contains all four of the
- parameters as input data and it calls the method named initialize()
- of class vehicle within its implementation. You will notice that
- we must call the method using the scope resolution operator in line
- 97 since there is no object to call, only the class. Following the
- initialization, it is permissible to call the semi.efficiency()
- method in line 65 and 66 of the main program.
-
-
- page 8-3
-
- Chapter 8 - More Inheritance
-
-
- Be sure to compile and execute this program following your detailed
- study of it.
-
-
- WHAT IS PROTECTED DATA?
- _________________________________________________________________
-
- Examine the program named INHERIT4.CPP for our ================
- first example of the use of protected data. INHERIT4.CPP
- Just to make the program more versatile, we have ================
- returned to the use of the keyword public prior
- to the name of the parent classes in lines 18
- and 29 of the class definitions.
-
-
- If the data within a superclass were totally available in all
- classes inheriting that superclass, it would be a simple matter for
- a programmer to inherit the superclass into a derived class and
- have free access to all data in the parent class. This would
- completely override the protection afforded by the use of
- information hiding. For this reason, the data in a class are not
- automatically available to the methods of an inheriting class.
- There are times when you may wish to automatically inherit all
- variables directly into the subclasses and have them act just as
- though they were defined as a part of those classes also. For this
- reason, the designer of C++ has provided the keyword protected.
-
- In the present example program, the keyword protected is given in
- line 5 so that all of the data of the vehicle class can be directly
- imported into any derived classes but are not available outside of
- the class or derived classes. All data are automatically defaulted
- to private type if no specifier is given, as in all earlier
- programs in this chapter. The keyword private can be used as
- illustrated in lines 19 and 30 but adds nothing due to the default.
-
- You will notice that the variables named wheels and weight are
- available to use in the method named initialize() in lines 85
- through 91 just as if they were declared as a part of the car class
- itself, since they are used directly. We can now state the rules
- for the three means of defining variables and methods.
-
- private - The variables and methods are not available to any
- outside calling routines, and they are not available
- to any subclasses inheriting this class.
-
- protected - The variables and methods are not available to any
- outside calling routines, but they are available to
- any subclass inheriting this class.
-
- public - All variables and methods are freely available to all
- outside calling routines and to all subclasses.
-
-
-
-
- page 8-4
-
- Chapter 8 - More Inheritance
-
- You will note that these three means of definition can also be used
- in a struct type. The only difference with a struct is that
- everything defaults to public until one of the other keywords is
- used.
-
- Be sure to compile and execute this program before continuing on
- to the next example program.
-
-
- INHERITING CONSTRUCTORS
- _________________________________________________________________
-
- Examine the example program named INHERIT5.CPP ================
- for yet another variation to our basic program, INHERIT5.CPP
- this time adding constructors. ================
-
- The vehicle class has a constructor to
- initialize the number of wheels and the weight to the indicated
- values and has no surprising constructs. The car and truck classes
- each have a constructor also to initialize their unique variables
- to some unique values. If you jump ahead to the main program, you
- will find that the initializing statements are commented out for
- each of the objects so we must depend on the constructors to
- initialize the variables. The most important thing to glean from
- this example program is the fact that when one of the constructors
- is called for a derived class, the constructor is also called for
- the parent class. In fact, the constructor for the parent class
- will be called before the constructor for the derived class is
- called. All of the data will be initialized, including the data
- inherited from the parent class.
-
- Be sure to compile and execute this example program.
-
-
- POINTERS TO AN OBJECT AND AN ARRAY OF OBJECTS
- _________________________________________________________________
-
- Examine the final example program in this ================
- chapter named INHERIT6.CPP for examples of the INHERIT6.CPP
- use of an array of objects and a pointer to an ================
- object.
-
- The program is identical to the first program in this chapter until
- we get to the main program where we find an array of 3 objects of
- class car declared in line 51. It should be obvious that any
- operation that is legal for a simple object is legal for an object
- that is part of an array, but we must be sure to tell the system
- which object of the array we are interested in by adding the array
- subscript as we do in lines 55 through 61. The operation of this
- portion of the program should be very easy for you to follow, so
- we will go on to the next construct of interest.
-
- You will notice, in line 64, that we do not declare an object of
- type truck but a pointer to an object of type truck. In order to
-
- page 8-5
-
- Chapter 8 - More Inheritance
-
- use the pointer, we must give it something to point at which we do
- in line 66 by dynamically allocating an object. Once the pointer
- has an object to point to, we can use the object in the same way
- we would use any object, but we must use the pointer notation to
- access any of the methods of the object. This is illustrated for
- you in lines 67 through 71, and will be further illustrated in the
- example programs of chapters 12 and 13 of this tutorial.
-
- Finally, we deallocate the object in line 72. You should spend
- enough time with this program to thoroughly understand the new
- material presented here, then compile and execute it.
-
-
- PROGRAMMING EXERCISES
- _________________________________________________________________
-
-
- 1. Remove the comment delimiters from lines 65 and 66 of
- INHERIT2.CPP to see what kind of results are returned. Remove
- them from line 56 to see what kind of an error is reported by
- the compiler for this error.
-
- 2. Add cout statements to each of the constructors of
- INHERIT5.CPP to output messages to the monitor so you can see
- the order of sending messages to the constructors.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- page 8-6